package org.will.cqrs.command;

import org.reveno.atp.api.commands.CommandContext;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * Created by EdifierWill on 2016/8/11.
 */
public abstract class Command<TDomainModel> implements ICommand<TDomainModel> {

    Class<TDomainModel> _domainModelClass;

    private boolean _makeNewId = false;

    private long _newId;

    public void setDomainModelClass(Class<TDomainModel> domainModelClass)
    {
        _domainModelClass = domainModelClass;
    }

    private Class<TDomainModel>  getDomainModelClass()
    {
        Type genType = this.getClass().getGenericSuperclass();
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        return (Class<TDomainModel>) params[0];
    }

    public void needNewId(boolean makeNewId){
        _makeNewId = makeNewId;
    }

    public Long getNewId(){
        return _newId;
    }

    public void handleCommand(ICommand cmd, CommandContext ctx) throws Exception {

        if(_makeNewId){
            //当设置后,避免反射导致的效率损失
            if(_domainModelClass==null){
                _newId = ctx.id(getDomainModelClass());
            }else{
                _newId = ctx.id(_domainModelClass);
            }
        }

        ctx.executeTxAction(createAction(cmd));
    }

    public abstract ICommandAction createAction(ICommand cmd);
}
